﻿using MessagePack;
using SysJsonIgnore = System.Text.Json.Serialization.JsonIgnoreAttribute;

namespace Basic.Base.Serialization;

[MessagePackObject]
public class SerializeDto
{
    [Key(0)]
    public string? TypeName { get; set; }

    [Key(1)]
    public string? AssemblyName { get; set; }

    [Key(2)]
    public string? Base64Str { get; set; }

    private byte[]? Data
    {
        get => string.IsNullOrEmpty(Base64Str) ? null : Convert.FromBase64String(Base64Str);
        set => Base64Str = value?.Length > 0 ? Convert.ToBase64String(value) : null;
    }

    [IgnoreMember]
    [Newtonsoft.Json.JsonIgnore]
    [SysJsonIgnore]
    public object? DataObj;

    public void SerializeObj(object obj)
    {
        Type type = obj.GetType();
        DataObj = obj;
        TypeName = type.FullName;
        AssemblyName = type.Assembly.GetName().Name;

        if (type.GetCustomAttribute<MessagePack.MessagePackObjectAttribute>() != null)
            Data = BaseSerializer.MessagePack.Serialize(obj);
        else
            Data = BaseSerializer.Json.Serialize(obj);
    }

    public object Derialize()
    {
        if (!string.IsNullOrEmpty(TypeName) && !string.IsNullOrEmpty(AssemblyName))
        {
            Type type = TypeExtension.LoadType(AssemblyName, TypeName);

            if (!string.IsNullOrEmpty(Base64Str) && type?.GetCustomAttribute<MessagePack.MessagePackObjectAttribute>() != null)
                return DataObj = BaseSerializer.MessagePack.Deserialize(Data, type);

            else if (!string.IsNullOrEmpty(Base64Str))
                return DataObj = BaseSerializer.Json.Deserialize(Data, type);
        }
        return default;
    }

    public T Derialize<T>() where T : class
    {
        T dataObj = default(T);
        if (!string.IsNullOrEmpty(TypeName) && !string.IsNullOrEmpty(AssemblyName))
        {
            var type = typeof(T);
            if (Data?.Length > 0 && type.GetCustomAttribute<MessagePack.MessagePackObjectAttribute>() != null)
                DataObj = BaseSerializer.MessagePack.Deserialize<T>(Data);
            else if (Data?.Length > 0)
                DataObj = BaseSerializer.Json.Deserialize<T>(Data);
        }
        return dataObj;
    }

}